//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	Identifier.cs
//  Developer:	Solomatov Igor
//  Created:	15.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using System.Diagnostics;

namespace Smart
{
	/// <summary>
	/// Entity Identifier
	/// </summary>
	[DebuggerDisplay("{Key}")]
	[Serializable]
	[DebuggerStepThrough]
	public struct Identifier : IEquatable<Identifier>
	{
		public static readonly Identifier Empty = default(Identifier);

		/// <summary>
		/// Identifier key value
		/// </summary>
		public object Key;

		/// <summary>
		/// Cast key value to Int
		/// </summary>
		public int Int
		{
			get { return (Key == null ? 0 : (int)Key); }
			set { Key = value; }
		}

		/// <summary>
		/// Cast key value to String
		/// </summary>
		public string String
		{
			get { return (string)Key; }
			set { Key = value; }
		}

		/// <summary>
		/// Cast key value to Guid
		/// </summary>
		public Guid Guid
		{
			get { return (Key == null ? Guid.Empty : (Guid)Key); }
			set { Key = value; }
		}

		/// <summary>
		/// Checks whether current identifier is empty
		/// </summary>
		public bool IsEmpty
		{
			get
			{
				return
					(Key == null) ||
					(Key is int
						 ? ((int)Key) <= 0
						 : (Key is Guid
								? ((Guid)Key) == Guid.Empty
								: Key is string && string.IsNullOrEmpty((string)Key)));
			}
		}

		/// <summary>
		/// Entity Identifier
		/// </summary>
		public Identifier(object key)
		{
			Key = key;
		}

		public bool Equals(Identifier other)
		{
			return
				Equals(Key, other.Key);
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
				return false;

			return
				GetType() != obj.GetType()
					? Equals(Key, obj)
					: Equals(Key, ((Identifier)obj).Key);
		}

		public override int GetHashCode()
		{
			return Key.GetHashCode();
		}

		public override string ToString()
		{
			return Key.ToString();
		}

		public static bool operator ==(Identifier id1, Identifier id2)
		{
			return
				id1.Equals(id2);
		}

		public static bool operator !=(Identifier id1, Identifier id2)
		{
			return
				!id1.Equals(id2);
		}

		public static explicit operator int(Identifier id)
		{
			return id.Int;
		}

		public static explicit operator string(Identifier id)
		{
			return id.String;
		}

		public static explicit operator Guid(Identifier id)
		{
			return id.Guid;
		}

		public static implicit operator Identifier(int id)
		{
			return new Identifier(id);
		}

		public static implicit operator Identifier(string id)
		{
			return new Identifier(id);
		}

		public static implicit operator Identifier(Guid id)
		{
			return new Identifier(id);
		}
	}
}